<?php

namespace Core;

class Router
{
    protected $routes = [
        'GET' => [],
        'POST' => [],
        'DELETE' => [],
        'PUT' => []
    ];

    protected $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function addRoute($method, $route, $callback)
    {
        $route = trim($route);
        $this->routes[$method][$route] = $callback;
    }

    public function get($route, $callback)
    {
        $this->addRoute('GET', $route, $callback);
    }

    public function post($route, $callback)
    {
        $this->addRoute('POST', $route, $callback);
    }

    public function put($route, $callback)
    {
        $this->addRoute('PUT', $route, $callback);
    }

    public function delete($route, $callback)
    {
        $this->addRoute('DELETE', $route, $callback);
    }

    public function dispatch()
    {
        $url = $_SERVER['REQUEST_URI'] ?? '/';
        $url = explode('?', $url, 2)[0];
        $method = $_SERVER['REQUEST_METHOD'];

        // 移除末尾斜杠
        $url = rtrim($url, '/') ?: '/';

        // 查找匹配的路由
        if (isset($this->routes[$method][$url])) {
            $callback = $this->routes[$method][$url];

            if (is_callable($callback)) {
                call_user_func($callback);
            } elseif (is_string($callback)) {
                // 格式: Controller@method
                list($controller, $method) = explode('@', $callback);
                $this->callControllerMethod($controller, $method);
            }
        } else {
            // 尝试匹配动态路由
            $matched = false;
            foreach ($this->routes[$method] as $route => $callback) {
                // 将路由转换为正则表达式
                $pattern = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[a-z0-9-]+)', $route);
                $pattern = "#^$pattern$#";

                if (preg_match($pattern, $url, $matches)) {
                    $params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);

                    if (is_callable($callback)) {
                        call_user_func_array($callback, $params);
                    } elseif (is_string($callback)) {
                        list($controller, $method) = explode('@', $callback);
                        $this->callControllerMethod($controller, $method, $params);
                    }

                    $matched = true;
                    break;
                }
            }

            if (!$matched) {
                http_response_code(404);
                echo "Page not found";
            }
        }
    }

    protected function callControllerMethod($controller, $method, $params = [])
    {
        // 包含命名空间（根据实际命名空间调整）
        $controllerClass = 'App\\Controllers\\' . ucfirst($controller) . 'Controller';

        if (class_exists($controllerClass)) {
            // 使用容器解析控制器，支持依赖注入
            $controllerInstance = $this->container->make($controllerClass);

            if (method_exists($controllerInstance, $method)) {
                call_user_func_array([$controllerInstance, $method], $params);
            } else {
                throw new \Exception("Method $method not found in controller $controllerClass");
            }
        } else {
            throw new \Exception("Controller class $controllerClass not found");
        }
    }
}
